
package com.ray.tcc.dubbo.interceptor;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.dubbo.rpc.RpcContext;
import com.ray.tcc.common.bean.context.TccTransactionContext;
import com.ray.tcc.common.constant.CommonConstant;
import com.ray.tcc.common.utils.GsonUtils;
import com.ray.tcc.core.concurrent.threadlocal.TransactionContextLocal;
import com.ray.tcc.core.interceptor.TccTransactionInterceptor;
import com.ray.tcc.core.service.TccTransactionAspectService;

/**
 * @author ray
 */
@Component
public class DubboTccTransactionInterceptor implements TccTransactionInterceptor {

    private final TccTransactionAspectService tccTransactionAspectService;

    @Autowired
    public DubboTccTransactionInterceptor(TccTransactionAspectService tccTransactionAspectService) {
        this.tccTransactionAspectService = tccTransactionAspectService;
    }

    public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
        final String context = RpcContext.getContext().getAttachment(CommonConstant.TCC_TRANSACTION_CONTEXT);
        TccTransactionContext tccTransactionContext;
        if (StringUtils.isNoneBlank(context)) {
            tccTransactionContext =
                    GsonUtils.getInstance().fromJson(context, TccTransactionContext.class);
        } else {
            tccTransactionContext = TransactionContextLocal.getInstance().get();
        }
        return tccTransactionAspectService.invoke(tccTransactionContext, pjp);
    }
}
